package com.yoyo.yyadsdk.open;

import android.app.ActivityManager;
import android.app.IProcessObserver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseIntArray;

import com.anye.greendao.gen.LocalPullEntityDao;
import com.anye.greendao.gen.PullEntityDao;
import com.yoyo.yyadsdk.activity.EmptyActivity;
import com.yoyo.yyadsdk.activity.KeepActivity;
import com.yoyo.yyadsdk.activity.LockActivity;
import com.yoyo.yyadsdk.activity.LockActivity_;
import com.yoyo.yyadsdk.bean.dao.AdvScreenEntity;
import com.yoyo.yyadsdk.bean.dao.LocalPullEntity;
import com.yoyo.yyadsdk.bean.dao.PullEntity;
import com.yoyo.yyadsdk.broad.DismissReceiver;
import com.yoyo.yyadsdk.broad.ScreenStatusReceiver;
import com.yoyo.yyadsdk.config.PullFeature;
import com.yoyo.yyadsdk.serv.AppTablePlaqueService;
import com.yoyo.yyadsdk.serv.WindowBDService;
import com.yoyo.yyadsdk.serv.WindowBUService;
import com.yoyo.yyadsdk.serv.WindowBaseService;
import com.yoyo.yyadsdk.serv.WindowIDService;
import com.yoyo.yyadsdk.serv.WindowIUService;
import com.yoyo.yyadsdk.util.ActivityUtils;
import com.yoyo.yyadsdk.util.AdvUtils;
import com.yoyo.yyadsdk.util.GreenDaoManager;
import com.yoyo.yyadsdk.util.LogHelper;
import com.yoyo.yyadsdk.util.PullUtils;
import com.yoyo.yyadsdk.util.SpUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.yoyo.yyadsdk.config.Constants.ENABLED_STATUS;
import static com.yoyo.yyadsdk.util.ActivityUtils.appIsRunning;


public class MyProcessObserver extends IProcessObserver.Stub {
    private Context mContext;
    private List<String> names;
    private SparseArray<String> mRunningApp;
    private PullEntityDao pullEntityDao;
    private String lastAty = "";
    private PullEntity mPullEntity;

    public MyProcessObserver(Context context) {
        mContext = context;
        pullEntityDao = GreenDaoManager.getInstance().getDaoSession().getPullEntityDao();
        mRunningApp = new SparseArray<>();
        ActivityManager am = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE));
        List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = am.getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo processInfo : runningAppProcesses) {
            mRunningApp.put(processInfo.uid, processInfo.processName);
        }
    }

    @Override
    public void onForegroundActivitiesChanged(int pid, int uid, boolean foregroundActivities) {
        invoke(uid);
    }

    public void onProcessStateChanged(int pid, int uid, int procState) {
        invoke(uid);
        LogHelper.e("onProcessStateChanged");
    }

    public void onImportanceChanged(int pid, int uid, int importance) {
        invoke(uid);
    }

    private void invoke(int uid) {
        if (!SpUtil.getConfigEnable()) {
            LogHelper.e("已禁用");
            return;
        }
        if (!isScreenUnLocked()) {
            return;
        }
        ActivityManager activityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
        ComponentName topActivity = activityManager.getRunningTasks(1).get(0).topActivity;
        String runningActivity = topActivity.getClassName();
        String toPkgName = topActivity.getPackageName();

//        LogHelper.e("onForegroundActivitiesChanged runningActivity: " + runningActivity);
//        LogHelper.e("onForegroundActivitiesChanged toPkgName: " + toPkgName);
//        LogHelper.e("onForegroundActivitiesChanged toPkgName is Running: " + appIsRunning(mContext, toPkgName));
//        LogHelper.e("onForegroundActivitiesChanged ____________________________ ");

        if (runningActivity.endsWith(".recent.RecentsActivity"))
            return;
        if (!lastAty.equals(runningActivity)) {
            if (runningActivity.endsWith(".packageinstaller.InstallAppProgress") || runningActivity.endsWith(".packageinstaller.InstallInstalling")) {
                mContext.sendBroadcast(new Intent(ACTION_INSTALL_START));
            }
            List<String> homePackageName = getHomePackageName();
            pullManager(homePackageName, runningActivity, toPkgName, uid);
            adManager(homePackageName, runningActivity, toPkgName);
            lastAty = runningActivity;
            mRunningApp.put(uid, runningActivity);
            if (SpUtil.getResetRunningApps()) {
                mRunningApp.clear();
                ActivityManager am = ((ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE));
                List<ActivityManager.RunningAppProcessInfo> runningAppProcesses = am.getRunningAppProcesses();
                for (ActivityManager.RunningAppProcessInfo processInfo : runningAppProcesses) {
                    mRunningApp.put(processInfo.uid, processInfo.processName);
                }
            }
//            for (int i = 0; i < mRunningApp.size(); i++) {
//                LogHelper.e("onForegroundActivitiesChanged RunningApp:" + mRunningApp.keyAt(i) + "____" + mRunningApp.valueAt(i));
//            }
        }
    }

    public static final String ACTION_INSTALL_START = "com.dollkey.hdownload.DownLoadNormalService.action.ACTION_INSTALL_START";

    private boolean isScreenUnLocked() {
        if (PullFeature.SCREEN_STATE_ == 0) {
            boolean screenUnLocked = ScreenStatusReceiver.isScreenUnLocked(mContext);
            PullFeature.SCREEN_STATE_ = screenUnLocked ? PullFeature.SCREEN_STATE_UNLOCK : PullFeature.SCREEN_STATE_LOCK;
            return screenUnLocked;
        } else {
            return PullFeature.SCREEN_STATE_ == PullFeature.SCREEN_STATE_UNLOCK;
        }
    }

    private void pullManager(List<String> homePackageName, String runningActivity, String toPkgName, int uid) {
        if (homePackageName.contains(toPkgName) && runningActivity.endsWith(".Launcher"))
            return;
        if (runningActivity.equals(LockActivity.class.getName())
                || runningActivity.equals(LockActivity_.class.getName())
                || runningActivity.equals(KeepActivity.class.getName()))
            return;
        if (toPkgName.equals(mContext.getPackageName())) return;
        if (lastAty.contains(EmptyActivity.class.getName()) && mPullEntity != null) {
            //记录拉活信息到本地
//            LocalPullEntityDao localPullEntityDao = GreenDaoManager.getInstance().getDaoSession().getLocalPullEntityDao();
//            LocalPullEntity localPullEntity = new LocalPullEntity();
//            localPullEntity.setAction(mPullEntity.getAction());
//            localPullEntity.setTPkg(mPullEntity.getTPkg());
//            localPullEntity.setType(mPullEntity.getType());
//            localPullEntity.setPullTime(System.currentTimeMillis());
//            localPullEntityDao.insertOrReplace(localPullEntity);
//            mPullEntity.setPullTimes(mPullEntity.getPullTimes() + 1);
//            pullEntityDao.insertOrReplace(mPullEntity);
            mPullEntity = null;
            return;
        }
        //判断上次拉活时间
        if (System.currentTimeMillis() - PullFeature.getPullFeatureLastPullTime() < PullFeature.getPullFeatureInterval())
            return;
        //是否是监控的app
        mPullEntity = PullUtils.getPullEntity(PullFeature.PULL_LAUNCHER);
        if (mPullEntity != null && indexOfValueByValue(mPullEntity.getTPkg()) < 0) {
            EmptyActivity.launch(mContext, PullFeature.PULL_LAUNCHER, mPullEntity);
        }
    }

    private void adManager(List<String> homePackageName, String runningActivity, String toPkgName) {
        closeWindow(runningActivity);
        if (runningActivity.equals(LockActivity.class.getName())
                || runningActivity.equals(LockActivity_.class.getName())
                || runningActivity.equals(KeepActivity.class.getName()))
            return;

        if (homePackageName.contains(toPkgName) && runningActivity.endsWith(".Launcher")) {
            AdvScreenEntity lockScreen = AdvUtils.getLockScreen(PullFeature.ADV_TABLE_PLAQUE, PullFeature.ADV_BANNER_UP,
                    PullFeature.ADV_BANNER_DOWN, PullFeature.ADV_ICON_DOWN, PullFeature.ADV_ICON_UP, PullFeature.ADV_BANNER_UP_);
            if (lockScreen != null) {
                switch (lockScreen.getType()) {
                    case PullFeature.ADV_TABLE_PLAQUE:
                        startAty(lockScreen);
                        break;
                    case PullFeature.ADV_BANNER_UP:
//                        startWindow(WindowBUService.class, lockScreen, runningActivity);
                        break;
                    case PullFeature.ADV_BANNER_DOWN:
                        startWindow(WindowBDService.class, lockScreen, runningActivity);
                        break;
                    case PullFeature.ADV_ICON_UP:
                        startWindow(WindowIUService.class, lockScreen, runningActivity);
                        break;
                    case PullFeature.ADV_ICON_DOWN:
                        startWindow(WindowIDService.class, lockScreen, runningActivity);
                        break;
                    case PullFeature.ADV_BANNER_UP_:
                        mContext.startService(new Intent(mContext, WindowBUService.class)
                                .putExtra("aty", runningActivity)
                                .putExtra("adv", lockScreen));
                        break;
                }
            }
            stopServ();
        } else {
            AdvScreenEntity lockScreen = AdvUtils.getLockScreen(PullFeature.ADV_APP_TABLE_PLAQUE);
            if (lockScreen != null) {
                startServ(lockScreen, toPkgName);
            } else {
                stopServ();
            }
        }
    }

    private void closeWindow(String runningActivity) {
        Intent intent = new Intent(DismissReceiver.ACTION);
        intent.putExtra("aty", runningActivity);
        mContext.sendBroadcast(intent);
    }

    private void startWindow(Class<? extends WindowBaseService> WindowBaseService, AdvScreenEntity lockScreen, String runningActivity) {
        mContext.startService(new Intent(mContext, WindowBaseService)
                .putExtra("aty", runningActivity)
                .putExtra("adv", lockScreen));
    }

    private void startAty(AdvScreenEntity lockScreen) {
        mContext.startActivity(new Intent(mContext, KeepActivity.class)
                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                .addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
                .putExtra("adv", lockScreen));
    }

    private void startServ(AdvScreenEntity lockScreen, String toPkgName) {
//        if (lockScreen != null && indexOfValueByValue(toPkgName) < 0)
        if (lockScreen != null)
            mContext.startService(new Intent(mContext, AppTablePlaqueService.class)
                    .putExtra("adv", lockScreen));
    }

    private void stopServ() {
        mContext.stopService(new Intent(mContext, AppTablePlaqueService.class));
    }

    private boolean isHome(String packageName) {
        return getHomePackageName().contains(packageName);
    }

    private List<String> getHomePackageName() {
        if (names == null) {
            names = new ArrayList<>();
            PackageManager packageManager = mContext.getPackageManager();
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_HOME);
            List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(intent,
                    PackageManager.MATCH_DEFAULT_ONLY);
            for (ResolveInfo ri : resolveInfo) {
                names.add(ri.activityInfo.packageName);
            }
        }
        return names;
    }

    public int indexOfValueByValue(String value) {
        int size = this.mRunningApp.size();
        for (int i = 0; i < size; ++i) {
            String s = mRunningApp.valueAt(i);
            if (value == null) {
                if (s == null) {
                    return i;
                }
            } else if (value.contains(s) || s.contains(value)) {
                return i;
            }
        }
        return -1;
    }

    @Override
    public void onProcessDied(int pid, int uid) {
        mRunningApp.remove(uid);
    }
}
